package hr.ctg.domain.action.otok;

import hr.ctg.domain.action.gmaps.GoogleMapsAction;
import hr.ctg.domain.model.Mjesto;
import hr.ctg.domain.model.Objekt;
import hr.ctg.domain.model.Otok;
import hr.ctg.domain.model.Posjet;
import hr.ctg.domain.model.Rola;
import hr.ctg.domain.model.TipObjekta;
import hr.ctg.domain.model.Rola.Role;
import hr.ctg.service.dao.MjestoDAO;
import hr.ctg.service.dao.ObjektDAO;
import hr.ctg.service.dao.OtokDAO;
import hr.ctg.service.dao.PosjetDAO;
import hr.ctg.service.dao.SlikaDAO;
import hr.ctg.service.dao.TipObjektaDAO;

import java.sql.Date;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.faces.context.FacesContext;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Identity;
import org.joda.time.DateTime;

@Name("otokDetailsAction")
@Scope(ScopeType.CONVERSATION)
public class OtokDetailsAction {
	@Logger
	Log log;

	@In
	FacesContext facesContext;
	@In
	String currentLang;
	@In
	PosjetDAO posjetDAO;
	@In
	OtokDAO otokDAO;
	@In
	ObjektDAO objektDAO;
	@In(create = true)
	GoogleMapsAction googleMapsAction;
	@In
	SlikaDAO slikaDAO;
	@In
	Identity identity;
	@In
	MjestoDAO mjestoDAO;
	@In
	TipObjektaDAO tipObjektaDAO;

	@Out(required = false)
	private Otok otokDetails;

	@RequestParameter
	private Integer idOtoka;
	@RequestParameter
	private Integer idTipaObjekta;

	@Factory(value = "otokDetails", autoCreate = true)
	@Transactional
	public void getOtokDetails() {
		if (idOtoka != null) {
			otokDetails = otokDAO.find(idOtoka);
			otokDetails.setBrojSlika(slikaDAO.findCountByIdOtoka(
					otokDetails.getIdOtoka()).intValue());
			log.debug("Otok broji " + otokDetails.getMjestos().size()
					+ " mjesta", new Object[0]);

			otokDetails.setBrojPosjeta(otokDAO.findBrojPosjeta(idOtoka)
					.intValue());

			// if (otokDetails.getLongituda() == null) {
			// final double[] coord = googleMapsAction.getLocation(otokDetails
			// .getNaziv());
			// if (coord != null) {
			// otokDetails.setLatituda(Double.valueOf(coord[0]));
			// otokDetails.setLongituda(Double.valueOf(coord[1]));
			// otokDetails.setZoom(Integer.valueOf(7));
			// otokDAO.merge(otokDetails);
			// }
			// }
		}
	}

	@Factory("mjestaByOtok")
	public List<Mjesto> getMjesta() {
		if (identity.hasRole(Role.ADMIN.toString())) {
			return mjestoDAO.findByIdOtoka(idOtoka);
		} else {
			return mjestoDAO.findByIdOtokaObjOpObjJezik(idOtoka, currentLang);
		}
	}

	@Transactional
	public void registerOtokVisit() {
		if (idOtoka != null
				&& !identity.hasRole(Rola.Role.ADMIN.toString())
				&& (facesContext.getExternalContext().getSessionMap().get(
						"posjetOtoka" + idOtoka) == null || !((Boolean) facesContext
						.getExternalContext().getSessionMap().get(
								"posjetOtoka" + idOtoka)).booleanValue())) {
			final java.util.Date currDate = new DateTime().toDateMidnight()
					.toDate();
			Posjet po = posjetDAO.findByOtokDatumPosjete(idOtoka, currDate);
			if (po == null) {
				po = new Posjet();
				po.setOtok(otokDAO.find(idOtoka));
				po.setDatumPosjete(new Date(currDate.getTime()));
			}

			po.setBrojPosjeta(po.getBrojPosjeta() + 1);
			posjetDAO.merge(po);

			facesContext.getExternalContext().getSessionMap().put(
					"posjetOtoka" + idOtoka, Boolean.valueOf(true));
		}
	}

	public boolean hasTopObjekti() {
		return objektDAO.findCountByOcjenaBrojPosjetaIdOtoka(idOtoka) > 0L;
	}

	public boolean hasObjekti() {
		return objektDAO.findCountByIdOtoka(idOtoka) > 0 ? true : false;
	}

	@SuppressWarnings("unchecked")
	@Factory("objektiByOtok")
	@Begin(join = true)
	public List<Objekt> getObjekti() {
		if (idOtoka == null || idTipaObjekta == null) {
			return Collections.EMPTY_LIST;
		}
		final List<Objekt> l = objektDAO.findByIdOtokaIdTipaObjekta(idOtoka,
				idTipaObjekta);
		List projections = objektDAO.findOBDBSByIdObjektaList(l);
		if (l.size() > 0) {
			for (final Objekt objekt : l) {
				for (final Iterator<Object[]> localIterator2 = projections
						.iterator(); localIterator2.hasNext();) {
					final Object[] proj = localIterator2.next();
					if (proj[0].equals(objekt.getIdObjekta())) {
						objekt.setOcjena((Double) proj[1]);
						objekt.setBrojDojmova((Integer) proj[2]);
						objekt.setBrojSlika((Integer) proj[3]);
					}
				}
			}
		}
		return l;
	}

	@Factory("tipoviObjekataByOtok")
	public List<TipObjekta> getTipoviObjekata() {
		final Otok otok = otokDAO.find(idOtoka);
		if (otok != null) {
			return tipObjektaDAO.findByIdOtoka(Integer.valueOf(otok
					.getIdOtoka()));
		}

		return null;
	}
}